package vectors;

import java.util.Iterator;

public class ArrayVector implements Vector {
	private static final long serialVersionUID = -198214762553662722L;
	private double[] elements;

	public ArrayVector(int length) {
		elements = new double[length];
	}

    /* TODO все тело метода можно заменить строкой
    *  elements = values.clone();
    */
	public ArrayVector(double... values) {
		elements = new double[values.length];
		for (int i = 0; i < values.length; i++) {
			elements[i] = values[i];
		}
	}

	@Override
	public double getElement(int index) {
		return elements[index];
	}

	@Override
	public void setElement(int index, double value) {
		elements[index] = value;
	}

	@Override
	public int getLength() {
		return elements.length;
	}

	@Override
	public void fillFromAnArray(double[] source) {
		if (source.length != elements.length) {
			System.out.println("Vector can't be filled.\n");
			return;
		}
		for (int i = 0; i < elements.length; i++) {
			elements[i] = source[i];
		}
	}

	@Override
	public void fillFromAnotherVector(Vector source) {
		if (source.getLength() != elements.length) {
			System.out.println("Vector can't be filled.\n");
			return;
		}
		for (int i = 0; i < elements.length; i++) {
			elements[i] = source.getElement(i);
		}
	}

	@Override
	public void multiplyByNumber(double number) {
		for (int i = 0; i < elements.length; i++) {
			elements[i] *= number;
		}
	}

	@Override
	public void add(Vector v) {
		if (elements.length != v.getLength()) {
			System.out.println("Vectors can't be added.\n");
			return;
		}
		for (int i = 0; i < elements.length; i++) {
			elements[i] += v.getElement(i);
		}
	}

	@Override
	public void compare(Vector v) {
		if (elements.length != v.getLength()) {
			System.out.println("Vectors are different.\n");
			return;
		}
		for (int i = 0; i < elements.length; i++) {
			if (elements[i] != v.getElement(i)) {
				System.out.println("Vectors are different.\n");
				return;
			}
		}
		System.out.println("Vectors are equal.\n");
	}

	@Override
	public String toString() {
		StringBuffer s = new StringBuffer("ArrayVector containing ");
		s.append(getLength());
		s.append(" elements which are:\n");
		for (int i = 0; i < elements.length; i++) {
			s.append(elements[i]);
			s.append('\n');
		}
		return s.toString();
	}

	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof Vector)) {
			return false;
		}
		Vector v = (Vector) obj;
		if (getLength() != v.getLength()) {
			return false;
		}
		for (int i = 0; i < getLength(); i++) {
			if (elements[i] != v.getElement(i)) {
				return false;
			}
		}
		return true;
	}

	@Override
	public int hashCode() {
		int hashCode = 0;
		for (int i = 0; i < getLength(); i++) {
			Double element = getElement(i);
			hashCode ^= element.hashCode();
		}
		return hashCode;
	}

	@Override
	public Object clone() {
		ArrayVector result = null;
		try {
			result = (ArrayVector) super.clone();
			result.elements = this.elements.clone();
		} catch (CloneNotSupportedException ex) {
		}
		return result;
	}

    //TODO можно было вынести все итераторы в отдельный пакет
	class ArrayVectorIterator implements Iterator<Double> {
		private int index;

		public ArrayVectorIterator() {
			index = 0;
		}

		@Override
		public boolean hasNext() {
			return index < elements.length;
		}

		@Override
		public Double next() {
			return getElement(index++);
		}

		@Override
		public void remove() {

		}
	}

	@Override
	public Iterator<Double> iterator() {
		return new ArrayVectorIterator();
	}

	public void printElements() {
		System.out.println("Vector has " + elements.length + " elements.");
		for (int i = 0; i < elements.length; i++) {
			System.out.println(elements[i]);
		}
		System.out.println();
	}
}
